package com.haoze.nurse.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.haoze.common.dto.CronDescriber;
import com.haoze.common.model.OrdersFileIndexEntity;
import com.haoze.common.model.TaskExecuteBatchEntity;
import com.haoze.common.response.Result;
import com.haoze.common.response.ResultGenerator;
import com.haoze.common.utils.CronUtil;
import com.haoze.common.utils.DateUtil;
import com.haoze.common.utils.HttpClientUtil;
import com.haoze.common.utils.UUIDUtil;
import com.haoze.nurse.dao.NurseOrdersMapper;
import com.haoze.nurse.dao.PrintMarkMapper;
import com.haoze.nurse.dao.TaskExecuteBatchMapper;
import com.haoze.nurse.dto.NursePatientDTO;
import com.haoze.nurse.dto.SpecilmenDetailLisDto;
import com.haoze.nurse.dto.SpecimenExtraDto;
import com.haoze.nurse.dto.lab.LabSpecimenSearchDto;
import com.haoze.nurse.enumeration.NurseEnum;
import com.haoze.nurse.enumeration.StateEnum;
import com.haoze.nurse.enumeration.TaskEnum;
import com.haoze.nurse.feign.DoctorPatientOrderService;
import com.haoze.nurse.feign.NurseAppFeignService;
import com.haoze.nurse.model.PrintMarkEntity;
import com.haoze.nurse.model.TaskNodeEntity;
import com.haoze.nurse.service.PatientOrderService;
import com.haoze.nurse.vo.Commodel;
import com.haoze.nurse.vo.EmrFile;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Author: Chenchao
 * @CreateTime: 2020-03-12 13:40
 */
@Service
public class PatientOrderServiceImpl implements PatientOrderService {

    private static Logger logger = LoggerFactory.getLogger(PatientOrderServiceImpl.class);
    private SimpleDateFormat hhmm = new SimpleDateFormat("HH:mm");
    @Resource
    private NurseOrdersMapper nurseOrdersMapper;

    @Resource
    private PrintMarkMapper printMarkMapper;
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;
    @Autowired
    NurseAppFeignService nurseAppFeignService;
    @Autowired
    TaskExecuteBatchMapper taskExecuteBatchMapper;
    @Resource
    DoctorPatientOrderService doctorPatientOrderService;
    @Value("${lis.url.specimen}")
    private String lisUrl;


    @Override
    public Result orderQRCodeNew(String inpatNum, String dateTime, String type, String printType, String administration, String freqTime, String ordersClass, String administrationFilter) {
        List<String> staticWardList = nurseOrdersMapper.queryStaticAllocationWard(StateEnum.SYLCZX.getValue());
        String beginTime = dateTime + " 00:00";
        String endTime = dateTime + " 23:59";
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, List<String>> printMap = new HashMap<>();
        Set<String> freqTimeSet = new HashSet<>();
        Set<String> administrationSet = new HashSet<>();
        //补打 补打按照打印时间查询
        if ("1".equals(printType)) {
            List<String> qrCodes = printMarkMapper.queryCodeByPrintTime(dateTime.replace("-", ""), inpatNum, NurseEnum.PRINT_THREE.getIndex(), administration, ordersClass);
            if (CollectionUtils.isEmpty(qrCodes)) {
                return ResultGenerator.genOkResult(list);
            }
            Set<String> ordersIds = new HashSet<String>();
            qrCodes.stream().forEach(x -> {
                String qCodes[] = x.split("_");
                String inpaNum = qCodes[1].substring(0, qCodes[1].length() - 14) + "-1";
                String orderNo = qCodes[2];
                String orderId = nurseOrdersMapper.queryPatientOrdersByInpatNumAndOrderNo(inpaNum, orderNo, administration);
                if (StringUtils.isNotBlank(orderId)) {
                    ordersIds.add(orderId);
                    List<String> qrList;
                    if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(printMap.get(orderId))) {
                        qrList = printMap.get(orderId);
                    } else {
                        qrList = new ArrayList<>();
                    }
                    qrList.add(x);
                    printMap.put(orderId, qrList);
                }
            });
            if (CollectionUtils.isEmpty(ordersIds)) {
                list = new ArrayList<>();
            } else {
                list = nurseOrdersMapper.queryOrderByIds(new ArrayList<>(ordersIds),staticWardList);
            }
        } else {
            //创建频次任务
            list = nurseOrdersMapper.orderQRCodeNew(inpatNum, beginTime, endTime, type, administration, ordersClass,staticWardList);
        }

        String finalBeginTime = beginTime;
        String finalEndTime = endTime;
        // 添加条码类型
        String codeType = this.nurseOrdersMapper.getAdministrationName(administration);
        list.parallelStream().forEach(map -> {
            computeAge(map);
            List<Map<String, Object>> orderList = nurseOrdersMapper.queryOrdersByInpatNum(map.get("inpatNum").toString(), map.get("orderNo").toString());
            map.put("orderList", orderList);
            map.put("codeType", codeType);
            Map<String, Object> mainOrder = orderList.get(0);
            try {
                if ("1".equals(printType)) {
                    List<Map<String, String>> qrCodeList = new CopyOnWriteArrayList<>();
                    printMap.get(map.get("inpatOrderId")).parallelStream().forEach(x -> {
                        Map<String, String> qrMap = new HashMap<String, String>();
                        qrMap.put("qrCode", x);
                        if (StringUtils.isNotEmpty(x)) {
                            String inpatStr = x.split("_")[1];
                            String dateTimeStr = inpatStr.replace(((String) map.get("inpatNum")).replace("-1", ""), "");
                            qrMap.put("execDate", new StringBuffer(dateTimeStr.substring(0, 4)).append("-").append(dateTimeStr, 4, 6)
                                    .append("-").append(dateTimeStr, 6, 8).append(" ").append(dateTimeStr, 8, 10).append(":")
                                    .append(dateTimeStr, 10, 12).append(":").append(dateTimeStr, 12, 14).toString());
                            String execDateStr = qrMap.get("execDate");
                            String hms = hhmm.format(DateUtil.stringToDate(execDateStr, "yyyy-MM-dd HH:mm:ss"));
                            freqTimeSet.add(hms);
                            administrationSet.add((String) mainOrder.get("administration"));
                            boolean filterFreq = true, administrationFilterFlag = true;
                            if (StringUtils.isNotBlank(freqTime)) {
                                if (hms.equals(freqTime)) {
                                    filterFreq = true;
                                } else {
                                    filterFreq = false;
                                }
                            }
                            if (StringUtils.isNotBlank(administrationFilter)) {
                                if (Arrays.asList(administrationFilter.split(",")).contains(mainOrder.get("administration"))) {
                                    administrationFilterFlag = true;
                                } else {
                                    administrationFilterFlag = false;
                                }
                            }
                            if (filterFreq && administrationFilterFlag) {
                                if (StringUtils.isNotBlank((String) mainOrder.get("execStatusHis")) && "3".equals((String) mainOrder.get("execStatusHis")) && StringUtils.isNotBlank((String) mainOrder.get("planEndDatetime"))) {
                                    Date execDate = DateUtil.stringToDate(execDateStr, "yyyy-MM-dd HH:mm:ss");
                                    Date endDate = DateUtil.stringToDate(mainOrder.get("planEndDatetime").toString(), "yyyy-MM-dd HH:mm:ss");
                                    if (execDate.before(endDate)) {
                                        qrCodeList.add(qrMap);
                                    }
                                } else {
                                    qrCodeList.add(qrMap);
                                }
                            }
                        }
                    });
                    map.put("qrCodeList", qrCodeList.stream().sorted(Comparator.comparing(o -> o.get("execDate"))).collect(Collectors.toList()));
                } else {
                    createFreQrCode(mainOrder, map, finalBeginTime, finalEndTime, printType, dateTime, administration, freqTime, freqTimeSet, administrationFilter, administrationSet);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });
        if (list.size() > 0) {
            list.get(0).put("freqList", freqTimeSet.stream().sorted(String::compareTo).collect(Collectors.toCollection(LinkedHashSet::new)));
            System.out.println(administrationSet);
            list.get(0).put("administrationList", administrationSet.stream().sorted(String::compareTo).collect(Collectors.toCollection(LinkedHashSet::new)));

        }
        /*List<Map<String, Object>> resultList = new ArrayList<>();
        LinkedHashSet<String> freqListCollect = freqTimeSet.stream().sorted(String::compareTo).collect(Collectors.toCollection(LinkedHashSet::new));
        LinkedHashSet<String> administrationListCollect = administrationSet.stream().sorted(String::compareTo).collect(Collectors.toCollection(LinkedHashSet::new));
        if (list.size() > 0) {
            //list.get(0).put("freqList", freqTimeSet.stream().sorted(String::compareTo).collect(Collectors.toCollection(LinkedHashSet::new)));
            //list.get(0).put("administrationList", administrationSet.stream().sorted(String::compareTo).collect(Collectors.toCollection(LinkedHashSet::new)));
            list.parallelStream().forEachOrdered(x->{
                List<Map<String, String>> newQrCodeList = (List<Map<String, String>>)x.get("qrCodeList");
                if(!CollectionUtils.isEmpty(newQrCodeList)){
                    newQrCodeList.parallelStream().forEachOrdered(y->{
                        Map<String, Object> copyMap = new ConcurrentHashMap<>(x);
                        List<Map<String, String>> newQrCode = new CopyOnWriteArrayList<>();
                        newQrCode.add(y);
                        copyMap.put("newQrCodeList",newQrCode);
                        copyMap.put("freqList", freqListCollect);
                        copyMap.put("administrationList", administrationListCollect);
                        resultList.add(copyMap);
                    });
                }
                //x.remove("qrCodeList");
            });
        }

        int totalLength = 0;
        List<Map<String, Object>> lastResultList = new ArrayList<>();
        //排序
        if(!CollectionUtils.isEmpty(resultList)){
            totalLength = resultList.size();

            if (page != 0 && pageSize != 0) {
                lastResultList = resultList.stream().skip((page - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
            }
        }
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(lastResultList);
        pageInfo.setTotal(totalLength);
        return ResultGenerator.genOkResult(pageInfo);*/
        return ResultGenerator.genOkResult(list);
    }

    /**
     * 按间隔时间创建任务
     *
     * @param nowDate
     * @param map
     */
    void createByTimeNextNode(Date nowDate, Map<String, String> map) {
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        //创建间隔时间任务
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //计划结束时间
            if (null == map.get("PLAN_END_DATETIME")) {
                map.put("PLAN_END_DATETIME", "2999-01-01 00:00:00");
            }
            Date planEndTime = sdf.parse(map.get("PLAN_END_DATETIME"));
            //执行间隔，单位：秒
            Date finallyDate = null;
            Date startTime = DateUtil.stringToDate(map.get("START_TIME"));
            AtomicInteger atomicInteger = new AtomicInteger(1);
            AtomicInteger atomicInteger2 = new AtomicInteger(1);
            //得出明天0点的时间
            Date nextDay = DateUtil.getDateAfter(nowDate, 1);
            Date nextDate = null;
            //计算下个创建任务的时间
            if (null == map.get("LAST_EXECUTE_TIME") || "".equals(map.get("LAST_EXECUTE_TIME"))) {
                nextDate = DateUtil.increasedSeconds(sdf.parse(map.get("PLAN_BEGIN_DATETIME")), Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
            } else {
                nextDate = DateUtil.increasedSeconds(sdf.parse(map.get("LAST_EXECUTE_TIME")), Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
            }
            //如果间隔时间小于明天0点,并且等于第二天0点，那就创建任务，防止第二天0点只计算间隔时间，可能会忽略本身的0点，那就创建任务
            while (nextDate.getTime() <= nextDay.getTime() && nextDate.getTime() <= planEndTime.getTime()) {
                Map<String, String> taskMap = nurseOrdersMapper.getEmrFileIdFromExec(map.get("INPATORDERDATA_ID"));
                if (null != taskMap && StringUtils.isNotEmpty(taskMap.get("EMR_FILE_ID"))) {
                    //此次执行时间需要在计划开始时间之后
                    if (nextDate.after(DateUtil.stringToDate(map.get("PLAN_BEGIN_DATETIME")))) {
                        String serialNo = "";
                        long cycle = (nextDate.getTime() - startTime.getTime()) / 1000 / Integer.parseInt(map.get("EXE_CYCLE_STAMP")) + 1;
                        TaskExecuteBatchEntity taskBatch = nurseOrdersMapper.queryTaskBatch(cycle);
                        if (null != taskBatch) {
                            //计算下一个间隔任务时间
                            nextDate = DateUtil.increasedSeconds(nextDate, Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
                            continue;
                        }
                        if (cycle != atomicInteger.longValue()) {
                            atomicInteger2 = new AtomicInteger(1);
                            atomicInteger = new AtomicInteger((int) cycle);
                        }
                        if (cycle == atomicInteger.longValue()) {
                            serialNo = "_" + cycle + "_" + atomicInteger2.getAndIncrement();
                        }
                        logger.info("emrFileId = " + taskMap.get("EMR_FILE_ID"));
                        //获取文书
                        OrdersFileIndexEntity emrFileIndex;
                        try {
                            EmrFile emrFile = nurseAppFeignService.getFileIndex(taskMap.get("EMR_FILE_ID"));
                            emrFileIndex = emrFile.getEmrFileIndexEntity();
                        } catch (Exception e) {
                            //计算下一个间隔任务时间
                            nextDate = DateUtil.increasedSeconds(nextDate, Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
                            logger.error(e.getMessage());
                            continue;
                        }
                        logger.info("医嘱id：" + map.get("INPATORDERDATA_ID"));
                        Map<String, String> injectMap = nurseOrdersMapper.getMoveInjectTaskIdAndNodeId(map.get("INPATORDERDATA_ID"));
                        if (null == injectMap) {
                            break;
                        }
                        TaskNodeEntity taskNodeEntity = new TaskNodeEntity();
                        taskNodeEntity.setTaskId(injectMap.get("TASK_ID"));
                        taskNodeEntity.setTaskNodeId(injectMap.get("TASK_NODE_ID"));
                        //执行任务流程
                        TaskExecuteBatchEntity taskExecuteBatch = createTaskExecute(cycle, taskMap, map.get("INPATORDERDATA_ID"),
                                TaskEnum.EXECUTED.getValue(), taskNodeEntity, emrFileIndex, nextDate, map.get("INPATORDERDATA_ID") + serialNo);
//						//触发下一个任务节点
                        doctorPatientOrderService.createNextTaskNode(
                                taskExecuteBatch.getTaskExecuteDetailId()
                                , taskExecuteBatch.getBatchNo().intValue()
                                , emrFileIndex.getDoctorId()
                                , ""
                                , ""
                                , DateUtil.dateToString(nextDate, "yyyy-MM-dd HH:mm:ss"));
                    }
                    finallyDate = nextDate;
                }
                //计算下一个间隔任务时间
                nextDate = DateUtil.increasedSeconds(nextDate, Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
            }
            if (null != finallyDate)
                nurseOrdersMapper.updateOrderExecuteTime(map.get("INPATORDERDATA_ID"), finallyDate);
            dataSourceTransactionManager.commit(transactionStatus);//提交
        } catch (ParseException e) {
            dataSourceTransactionManager.rollback(transactionStatus);
            logger.error(e.getMessage());
        }
    }

    /**
     * 按频次创建任务
     *
     * @param nowDate
     * @param map
     */
    @Transactional(rollbackFor = Exception.class)
    public void createNextNode(Date nowDate, Map<String, String> map) {
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            //计算下个创建任务的时间
            Date nextDate = DateUtil.increasedSeconds(nowDate, Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
            //得出明天0点的时间
            Date nextDay = DateUtil.getDateAfter(nowDate, 1);
            if (nextDate.before(nextDay)) {
                nextDate = nextDay;
            }
            CronExpression cronExpression = null;
            try {
                CronDescriber cronDescriber = JSONObject.parseObject(map.get("CRON_DESCRIBER"), CronDescriber.class);
                String expression = CronUtil.createCronExpression(cronDescriber, null);
                cronExpression = new CronExpression(expression);
            } catch (ParseException e) {
                logger.error("转换corn失败", e);
            }
            //设置nextExecDate为今天0点
            Date nextExecDate = nowDate;
            Date finallyDate = null;
            Date startTime = DateUtil.stringToDate(map.get("START_TIME"));
            AtomicInteger atomicInteger = new AtomicInteger(1);
            AtomicInteger atomicInteger2 = new AtomicInteger(1);
            //计划结束时间
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (null == map.get("PLAN_END_DATETIME")) {
                map.put("PLAN_END_DATETIME", "2999-01-01 00:00:00");
            }
            Date planEndTime = null;
            try {
                planEndTime = sdf.parse(map.get("PLAN_END_DATETIME"));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            while (nextExecDate.before(nextDate)) {
                nextExecDate = cronExpression.getNextValidTimeAfter(nextExecDate);
                if (nextExecDate.before(nextDate) || nextExecDate.equals(nextDate)) {
                    Map<String, String> taskMap = nurseOrdersMapper.getEmrFileIdFromExec(map.get("INPATORDERDATA_ID"));
                    if (null != taskMap && StringUtils.isNotEmpty(taskMap.get("EMR_FILE_ID"))) {
                        //此次执行时间需要在计划开始时间之后
                        if (nextExecDate.after(DateUtil.stringToDate(map.get("PLAN_BEGIN_DATETIME"))) && nextExecDate.before(planEndTime)) {
                            String serialNo = "";
                            //计算出执行次数+1
                            long cycle = (nextExecDate.getTime() - startTime.getTime()) / 1000 / Integer.parseInt(map.get("EXE_CYCLE_STAMP")) + 1;
                            TaskExecuteBatchEntity taskBatch = nurseOrdersMapper.queryTaskBatch(cycle);
                            if (null != taskBatch) {
                                finallyDate = nextExecDate;
                                continue;
                            }
                            if (cycle != atomicInteger.longValue()) {
                                atomicInteger2 = new AtomicInteger(1);
                                atomicInteger = new AtomicInteger((int) cycle);
                            }
                            if (cycle == atomicInteger.longValue()) {
                                serialNo = "_" + cycle + "_" + atomicInteger2.getAndIncrement();
                            }
                            logger.info("emrFileId ： " + taskMap.get("EMR_FILE_ID"));
                            OrdersFileIndexEntity emrFileIndex;
                            try {
                                EmrFile emrFile = nurseAppFeignService.getFileIndex(taskMap.get("EMR_FILE_ID"));
                                emrFileIndex = emrFile.getEmrFileIndexEntity();
                            } catch (Exception e) {
                                logger.error(e.getMessage());
                                continue;
                            }
                            logger.info("医嘱id ： " + map.get("INPATORDERDATA_ID"));
                            Map<String, String> injectMap = nurseOrdersMapper.getMoveInjectTaskIdAndNodeId(map.get("INPATORDERDATA_ID"));
                            if (null == injectMap) {
                                break;
                            }
                            TaskNodeEntity taskNodeEntity = new TaskNodeEntity();
                            taskNodeEntity.setTaskId(injectMap.get("TASK_ID"));
                            taskNodeEntity.setTaskNodeId(injectMap.get("TASK_NODE_ID"));
                            //执行任务流程
                            TaskExecuteBatchEntity taskExecuteBatch = createTaskExecute(cycle, taskMap, map.get("INPATORDERDATA_ID"),
                                    TaskEnum.EXECUTED.getValue(), taskNodeEntity, emrFileIndex, nextExecDate, map.get("INPATORDERDATA_ID") + serialNo);
//						//触发下一个任务节点
                            doctorPatientOrderService.createNextTaskNode(
                                    taskExecuteBatch.getTaskExecuteDetailId()
                                    , taskExecuteBatch.getBatchNo().intValue()
                                    , emrFileIndex.getDoctorId()
                                    , ""
                                    , ""
                                    , DateUtil.dateToString(nextDate, "yyyy-MM-dd HH:mm:ss"));
                        }
                        finallyDate = nextExecDate;
                    }
                }
            }
            if (null != finallyDate)
                nurseOrdersMapper.updateOrderExecuteTime(map.get("INPATORDERDATA_ID"), finallyDate);
            dataSourceTransactionManager.commit(transactionStatus);//提交
        } catch (Exception e) {
            logger.error(e.getMessage());
            dataSourceTransactionManager.rollback(transactionStatus);
        }
    }

    /**
     * 生成任务执行
     *
     * @param cycle
     * @param taskMap
     * @param inpatorderdataId 医嘱id
     * @param emrFileIndex     文书
     * @return
     */
    public TaskExecuteBatchEntity createTaskExecute(long cycle, Map<String, String> taskMap, String inpatorderdataId, String execeted, TaskNodeEntity taskNodeEntity,
                                                    OrdersFileIndexEntity emrFileIndex, Date date, String qrCode) {
        //查询task_execute_id,task_execute_detail_id,node_name
        String taskBatchId = UUIDUtil.randomString();
        Map<String, Object> map = new HashMap<>();
        TaskExecuteBatchEntity taskExecuteBatch = new TaskExecuteBatchEntity();
        //计算当前应该生成的批次，并查询出当前批次-1的serial_no最大的数据，判断status是否是1
        TaskExecuteBatchEntity preTaskBatch = nurseOrdersMapper.queryTaskBatch(cycle - 1);
        if (null != preTaskBatch) {
            if (preTaskBatch.getStatus().equals("1")) {
                //如果是1则记录到当前批次的preTaskBatchId，并更新批次-1的nextTaskBatchId
                preTaskBatch.setNextTaskBatchId(taskBatchId);
                taskExecuteBatchMapper.updateByPrimaryKeySelective(preTaskBatch);
                taskExecuteBatch.setPreTaskBatchId(preTaskBatch.getTaskBatchId());
            }
        }
        taskExecuteBatch.initAdd();
        taskExecuteBatch.setInpatorderdataId(inpatorderdataId);
        taskExecuteBatch.setTaskExecuteDetailId(taskMap.get("TASK_EXECUTE_DETAIL_ID"));
        taskExecuteBatch.setTaskExecuteId(taskMap.get("TASK_EXECUTE_ID"));
        taskExecuteBatch.setTaskNodeId(taskNodeEntity.getTaskNodeId());
        taskExecuteBatch.setSerialNo(1);
        taskExecuteBatch.setStartDatetime(new Timestamp(date.getTime()));
        taskExecuteBatch.setStopDatetime(new Timestamp(date.getTime()));
        taskExecuteBatch.setEmrFileId(emrFileIndex.getEmrFileId());
        taskExecuteBatch.setQrCode(qrCode);
        taskExecuteBatch.setStatus(execeted);
        taskExecuteBatch.setExecutePersonId(emrFileIndex.getDoctorId());
        taskExecuteBatch.setBatchNo(cycle);
        taskExecuteBatch.setNodeName(taskMap.get("node_name"));
        taskExecuteBatch.setTaskBatchId(taskBatchId);
        taskExecuteBatchMapper.insert(taskExecuteBatch);
        return taskExecuteBatch;
    }


    @Override
    public Result orderQRCode(String inpatNum, String beginTime, String endTime, String printType, String search) {
        beginTime = beginTime + " 00:00";
        endTime = endTime + " 23:59";
        List<Map<String, Object>> list = nurseOrdersMapper.orderQRCode(inpatNum, beginTime, endTime);
        String finalBeginTime = beginTime;
        String finalEndTime = endTime;
        list.stream().forEach(map -> {
            computeAge(map);
            List<Map<String, Object>> orderList = nurseOrdersMapper.queryOrdersByInpatNum(map.get("inpatNum").toString(), map.get("orderNo").toString());
            map.put("orderList", orderList);
            Map<String, Object> mainOrder = orderList.get(0);
            try {
                createFreQrCode(mainOrder, map, finalBeginTime, finalEndTime, printType);
            } catch (ParseException e) {
                e.printStackTrace();
            }

        });
        return ResultGenerator.genOkResult(list);
    }


    public void computeAge(Map<String, Object> map) {
        if (map.get("birthDay") != null && map.get("inDatetime") != null) {
            // 计算年龄
            Calendar c1 = Calendar.getInstance();
            c1.setTime(DateUtil.stringToDate(map.get("birthDay").toString()));
            Calendar c2 = Calendar.getInstance();
            c2.setTime(DateUtil.stringToDate(map.get("inDatetime").toString()));

            int[] times = DateUtil.getTimeIntervalArray(c2, c1);
            int years = times[0];
            int months = times[1];
            int days = times[2];
            int hours = times[3];
            int minutes = times[4];
            if (years >= 3) {
                map.put("age", years + "岁");
            } else if (years >= 1) {
                map.put("age", years + "岁" + (months == 0 ? "" : months + "月"));
            } else if (months >= 1) {
                map.put("age", months + "月" + (days == 0 ? "" : days + "天"));
            } else if (days >= 1) {
                map.put("age", days + "天");
            } else if (hours >= 1) {
                map.put("age", hours + "小时" + (minutes == 0 ? "" : minutes + "分钟"));
            } else if (minutes >= 0) {
                map.put("age", minutes + "分钟");
            } else {
                map.put("age", (years == 0 ? "" : years + "岁") + (months == 0 ? "" : months + "月") + (days == 0 ? "" : days + "天") + (hours == 0 ? "" : hours + "小时") + (minutes == 0 ? "" : minutes + "分钟"));
            }
        } else { // 当出生日期或者入院日期无效则采用下面策略计算时间
            if (map.get("ageDay") == null) {
                map.put("age", (map.get("ageYear") == null ? "" : map.get("ageYear") + "岁") + (map.get("ageMonth") == null ? "" : map.get("ageMonth") + "月"));
            } else {
                if (map.get("minutes") == null) {
                    map.put("age", (map.get("ageYear") == null ? "" : map.get("ageYear") + "岁") + (map.get("ageMonth") == null ? "" : map.get("ageMonth") + "月") + (map.get("ageDay") == null ? "" : map.get("ageDay") + "天"));
                } else {
                    int days = Integer.parseInt(map.get("minutes").toString()) / 60 / 24;
                    int hour = Integer.parseInt(map.get("minutes").toString()) / 60 % 24;
                    map.put("age", (days == 0 ? (hour == 0 ? "" : hour + "小时") : days + "天"));
                }
            }
        }
    }


    private void createFreQrCode(Map<String, Object> mainOrder, Map<String, Object> result, String beginTime1, String endTime1, String printType, String date, String administration, String freqTime, Set<String> freqTimeSet, String administrationFilter, Set<String> administrationSet) throws ParseException {
        String executeDateStr = date.replaceAll("-", "");
        Date executeDate = DateUtil.stringToDate(executeDateStr, "yyyyMMdd");
        Date executeEndDateTime = DateUtil.getDateAfter(DateUtil.stringToDate(executeDateStr, "yyyyMMdd"), 1);
        List<Map<String, String>> qrCodeList = new ArrayList<>();
        String freq = result.get("freq") == null ? "" : result.get("freq").toString();
        String freqData = result.get("freqData") == null ? "" : result.get("freqData").toString();
        //  临时医嘱
        if (org.apache.commons.lang.StringUtils.isEmpty((String) result.get("TIMEMODE")) || result.get("orderType").equals("2")) {
            Date beginDateTime = DateUtil.stringToDate(result.get("planBeginDatetime").toString(), "yyyy-MM-dd HH:mm:ss");
            String begindateTimeFormat1 = DateUtil.dateToString(beginDateTime, "yyyyMMddHHmmss");
            String begindateTimeFormat2 = DateUtil.dateToString(beginDateTime, "yyyy-MM-dd HH:mm:ss");
            String oralCode = new StringBuffer("y_").append(result.get("medicalNum")).append(begindateTimeFormat1).append("_").append(result.get("orderNo")).toString();
            Map<String, String> map = new HashMap<String, String>();
            map.put("qrCode", oralCode);
            map.put("execDate", begindateTimeFormat2);
            String times = printMarkMapper.countByQrCode(oralCode, NurseEnum.PRINT_THREE.getIndex());
            times = StringUtils.isBlank(times) ? "0" : times;
            map.put("times", times);
            String hms = hhmm.format(beginDateTime);
            freqTimeSet.add(hms);
            if(StringUtils.isNotBlank((String) mainOrder.get("administration"))){
                administrationSet.add((String) mainOrder.get("administration"));
            }
            boolean filterFreq = true, administrationFilterFlag = true;
            if (StringUtils.isNotBlank(freqTime)) {
                if (hms.equals(freqTime)) {
                    filterFreq = true;
                } else {
                    filterFreq = false;
                }
            }
            if (StringUtils.isNotBlank(administrationFilter)) {
                if (Arrays.asList(administrationFilter.split(",")).contains(mainOrder.get("administration"))) {
                    administrationFilterFlag = true;
                } else {
                    administrationFilterFlag = false;
                }
            }
            if (filterFreq && administrationFilterFlag) {
                if ("0".equals(times) && printType.equals("0")) {
                    // 未打印类型，打印次数为0
                    qrCodeList.add(map);
                } else if (!"0".equals(times) && printType.equals("1")) {
                    // 打印类型，打印次数不为0
                    qrCodeList.add(map);
                }
            }
        } else if (result.get("TIMEMODE").equals("0")) {
            Date beginDateTime = DateUtil.stringToDate(result.get("planBeginDatetime").toString(), "yyyy-MM-dd HH:mm:ss");
            Date beginDate = DateUtil.stringToDate(result.get("planBeginDatetime").toString(), "yyyy-MM-dd");
            //如果指定时间的0点小于开始时间，则使用开始时间计算
            Date startTime = executeDate;
            if ("QOD".equals(result.get("freq"))) {
                startTime = beginDate;
            }
            Date eTime = null;
            if (result.get("planEndDatetime") != null) {
                eTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) result.get("planEndDatetime"));
            }
            Date endTime = result.get("planEndDatetime") == null ? executeEndDateTime : (eTime.compareTo(executeEndDateTime) >= 0 ? executeEndDateTime : eTime);
            CronDescriber cronDescriber = JSONObject.parseObject((String) result.get("CRON_DESCRIBER"), CronDescriber.class);
            String expression = CronUtil.createCronExpression(cronDescriber, startTime);
            CronExpression cronExpression = null;
            try {
                cronExpression = new CronExpression(expression);
            } catch (ParseException e) {
                e.printStackTrace();
                return;
            }
            startTime = cronExpression.getNextValidTimeAfter(startTime);

            String specialUsageFlag = result.get("administrationId") == null ? null : nurseOrdersMapper.querySpecialUsage(result.get("administrationId").toString());
            boolean qodAddFlag=true;

            while (startTime.before(executeEndDateTime) && (null == result.get("planEndDatetime") || startTime.before(endTime)) && qodAddFlag) {
                Map<String, String> map = new HashMap<String, String>();
                map.put("execDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTime));
                String oralCode = new StringBuffer("y_").append(result.get("medicalNum")).append(new SimpleDateFormat("yyyyMMddHHmmss").format(startTime)).append("_").append(result.get("orderNo")).toString();
                boolean addFlag = true;
                if ((StringUtils.isNotBlank(specialUsageFlag) && startTime.before(beginDateTime)) || (result.get("administrationId") == null && startTime.before(beginDateTime))) {
                    addFlag = false;
                }
                if(!executeDate.before(startTime)){
                    addFlag = false;
                }

                if(!("输液单".equals(result.get("codeType")) || "注射用".equals(result.get("administration")))){
                    if(!(!(!executeDate.before(startTime)) && ((executeDate.equals(beginDate) && (startTime.after(beginDateTime) || startTime.equals(beginDateTime))) || !executeDate.equals(beginDate)))){
                        addFlag = false;
                    }
                }
                String hms = hhmm.format(startTime);
                boolean filterFreq = true, administrationFilterFlag = true;
                if (StringUtils.isNotBlank(freqTime)) {
                    if (hms.equals(freqTime)) {
                        filterFreq = true;
                    } else {
                        filterFreq = false;
                    }
                }
                if (StringUtils.isNotBlank(administrationFilter)) {
                    if (Arrays.asList(administrationFilter.split(",")).contains(mainOrder.get("administration"))) {
                        administrationFilterFlag = true;
                    } else {
                        administrationFilterFlag = false;
                    }
                }
                startTime = cronExpression.getNextValidTimeAfter(startTime);
                map.put("qrCode", oralCode);
                String times = printMarkMapper.countByQrCode(oralCode, NurseEnum.PRINT_THREE.getIndex());
                times = StringUtils.isBlank(times) ? "0" : times;
                map.put("times", times);
                if (addFlag) {
                    if ("0".equals(times) && printType.equals("0")) {
                        if (filterFreq && administrationFilterFlag) {
                            // 未打印类型，打印次数为0
                            qrCodeList.add(map);
                        }
                        freqTimeSet.add(hms);
                        if(StringUtils.isNotBlank((String) mainOrder.get("administration"))){
                            administrationSet.add((String) mainOrder.get("administration"));
                        }
                    } else if (!"0".equals(times) && printType.equals("1")) {
                        if (filterFreq && administrationFilterFlag) {
                            // 打印类型，打印次数不为0
                            qrCodeList.add(map);
                        }
                        freqTimeSet.add(hms);
                        if(StringUtils.isNotBlank((String) mainOrder.get("administration"))){
                            administrationSet.add((String) mainOrder.get("administration"));
                        }
                    }
                }
            }
        } else {
            Date beginDateTime = DateUtil.stringToDate(result.get("planBeginDatetime").toString(), "yyyy-MM-dd HH:mm:ss");
            Date beginDate = DateUtil.stringToDate(result.get("planBeginDatetime").toString(), "yyyy-MM-dd");
            //如果指定时间的0点小于开始时间，则使用开始时间计算
            Date startTime = executeDate.equals(beginDate) ? beginDateTime : DateUtil.getDateAfterRedSecond(executeDate, 1);
            Date eTime = null;
            if (result.get("planEndDatetime") != null) {
                eTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) result.get("planEndDatetime"));
            }
            Date endTime = result.get("planEndDatetime") == null ? executeEndDateTime : (eTime.compareTo(executeEndDateTime) >= 0 ? executeEndDateTime : eTime);
            CronDescriber cronDescriber = JSONObject.parseObject((String) result.get("CRON_DESCRIBER"), CronDescriber.class);
            String expression = CronUtil.createCronExpression(cronDescriber, null);
            CronExpression cronExpression = null;
            try {
                cronExpression = new CronExpression(expression);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if (startTime.equals(beginDateTime) && result.get("TIMEMODE").equals("1")) {
                startTime = executeDate;
            }
            startTime = cronExpression.getNextValidTimeAfter(startTime);
            /*if (startTime.equals(DateUtil.getDateAfter(beginDateTime, 1)) || startTime.after(executeEndDateTime)) {//执行时间与创建时间一致.非间隔时间表达式会不包含.会向前推一天,需要判断后手动回
                startTime = DateUtil.getDateBefore(startTime, 1);
            }*/

            String specialUsageFlag = result.get("administrationId") == null ? null : nurseOrdersMapper.querySpecialUsage(result.get("administrationId").toString());

            while (startTime.before(executeEndDateTime) && (null == result.get("planEndDatetime") || startTime.before(endTime))) {
                Map<String, String> map = new HashMap<String, String>();
                map.put("execDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTime));
                String oralCode = new StringBuffer("y_").append(result.get("medicalNum")).append(new SimpleDateFormat("yyyyMMddHHmmss").format(startTime)).append("_").append(result.get("orderNo")).toString();
                boolean addFlag = true;
                if ((StringUtils.isNotBlank(specialUsageFlag) && startTime.before(beginDateTime)) || (result.get("administrationId") == null && startTime.before(beginDateTime))) {
                    addFlag = false;
                }
                String hms = hhmm.format(startTime);
                boolean filterFreq = true, administrationFilterFlag = true;
                if (StringUtils.isNotBlank(freqTime)) {
                    if (hms.equals(freqTime)) {
                        filterFreq = true;
                    } else {
                        filterFreq = false;
                    }
                }
                if (StringUtils.isNotBlank(administrationFilter)) {
                    if (Arrays.asList(administrationFilter.split(",")).contains(mainOrder.get("administration"))) {
                        administrationFilterFlag = true;
                    } else {
                        administrationFilterFlag = false;
                    }
                }
                startTime = DateUtil.increasedSeconds(startTime, Integer.parseInt((String) result.get("exeCycleStamp")));
                map.put("qrCode", oralCode);
                String times = printMarkMapper.countByQrCode(oralCode, NurseEnum.PRINT_THREE.getIndex());
                times = StringUtils.isBlank(times) ? "0" : times;
                map.put("times", times);
                if (addFlag) {
                    if ("0".equals(times) && printType.equals("0")) {
                        if (filterFreq && administrationFilterFlag) {
                            // 未打印类型，打印次数为0
                            qrCodeList.add(map);
                        }
                        freqTimeSet.add(hms);
                        if(StringUtils.isNotBlank((String) mainOrder.get("administration"))){
                            administrationSet.add((String) mainOrder.get("administration"));
                        }
                    } else if (!"0".equals(times) && printType.equals("1")) {
                        if (filterFreq && administrationFilterFlag) {
                            // 打印类型，打印次数不为0
                            qrCodeList.add(map);
                        }
                        freqTimeSet.add(hms);
                        if(StringUtils.isNotBlank((String) mainOrder.get("administration"))){
                            administrationSet.add((String) mainOrder.get("administration"));
                        }
                    }
                }
            }
        }
        result.put("qrCodeList", qrCodeList);
    }


    @Override
    /**
     * printStatus 0:全部 1 :未打印 2补打
     */
    public Result printOrderInfo(String type, String wardId, String search, String page, String pageSize, String printStatus,String printNum) {
        //List<Map<String, String>> pbstetricWardList = nurseOrdersMapper.queryObstetricWard(wardId);
        List<Map<String, String>> pbstetricWardList = nurseOrdersMapper.queryObstetricWard(wardId,StateEnum.NEWBORN_WARD.getValue());
        //boolean babyFlag=false;
        //boolean newBornFlag=false;
        //0 全打   1 只打成人  2 只打新生儿  3 不能打
        String flag = "0";
        //PageHelper.startPage(Integer.parseInt(page), Integer.parseInt(pageSize));
        // TODO: 床头牌任务
        List<NursePatientDTO> resultList = new ArrayList<>();
        List<NursePatientDTO> nursePatientDTOList = new ArrayList<>();
        if ("1".equals(type)) {
            //成人腕带
            if(!CollectionUtils.isEmpty(pbstetricWardList)){
                flag="1";
                if(StateEnum.OBSTETRICS_NEWBORN.getValue().equals(pbstetricWardList.get(0).get("varCode"))){
                //if(wardId.equals(pbstetricWardList.get(0).get("deptId"))){
                    flag="3";
                }
            }
            nursePatientDTOList = nurseOrdersMapper.queryPatientMsg(type, wardId, search, printStatus,flag);
        } else if("2".equals(type)){
            //床头牌
            nursePatientDTOList = nurseOrdersMapper.queryWardBedMsg(type, wardId, search, printStatus);
        } else if("3".equals(type)){
            //新生儿腕带
            if(!CollectionUtils.isEmpty(pbstetricWardList)){
                flag="2";
                if(StateEnum.OBSTETRICS_NEWBORN.getValue().equals(pbstetricWardList.get(0).get("varCode"))){
                //if(wardId.equals(pbstetricWardList.get(0).get("deptId"))){
                    flag="1";
                }
                nursePatientDTOList = nurseOrdersMapper.queryPatientMsg(type, wardId, search, printStatus,flag);
            }

        }

        nursePatientDTOList.parallelStream().forEach(dto -> {

            if (dto.getBirthDay() != null && dto.getInDateTime() != null) {
                Calendar c1 = Calendar.getInstance();
                c1.setTime(DateUtil.stringToDate(dto.getBirthDay()));
                Calendar c2 = Calendar.getInstance();
                c2.setTime(DateUtil.stringToDate(dto.getInDateTime()));

                int[] times = DateUtil.getTimeIntervalArray(c2, c1);
                int years = times[0];
                int months = times[1];
                int days = times[2];
                int hours = times[3];
                int minutes = times[4];

                if (years >= 3) {
                    dto.setAge(years + "岁");
                } else if (years >= 1 && years < 3) {
                    dto.setAge(years + "岁" + (months == 0 ? "" : months + "月"));
                } else if (years < 1 && months >= 1) {
                    dto.setAge(months + "月" + (days == 0 ? "" : days + "天"));
                } else if (days == 29) {
                    dto.setAge(days + "天");
                } else if (days <= 28 && days >= 1) {
                    dto.setAge(days + "天" + (hours == 0 ? "" : hours + "小时"));
                } else if (days < 1 && hours >= 1) {
                    dto.setAge(hours + "小时" + (minutes == 0 ? "" : minutes + "分钟"));
                } else if (hours < 1 && minutes >= 1) {
                    dto.setAge(minutes + "分钟");
                } else {
                    dto.setAge((dto.getAgeYear() == null ? "" : dto.getAgeYear() + "岁") + (dto.getAgeMonth() == null ? "" : dto.getAgeMonth() + "月") + (dto.getAgeDay() == null ? "" : dto.getAgeDay() + "天"));
                }

            } else { // 当出生日期或者入院日期无效则采用下面策略计算时间
                if (dto.getAgeDay() == null) {
                    dto.setAge((dto.getAgeYear() == null ? "" : dto.getAgeYear() + "岁") + (dto.getAgeMonth() == null ? "" : dto.getAgeMonth() + "月"));
                } else {
                    if (dto.getMinutes() == null) {
                        dto.setAge((dto.getAgeYear() == null ? "" : dto.getAgeYear() + "岁") + (dto.getAgeMonth() == null ? "" : dto.getAgeMonth() + "月") + (dto.getAgeDay() == null ? "" : dto.getAgeDay() + "天"));
                    } else {
                        int days = Integer.parseInt(dto.getMinutes()) / 60 / 24;
                        int hour = Integer.parseInt(dto.getMinutes()) / 60 % 24;
                        dto.setAge((days == 0 ? (hour == 0 ? "" : hour + "小时") : days + "天"));
                    }
                }
            }
            dto.setSex(dto.getSex() != null ? (dto.getSex().length()==2?dto.getSex().replaceAll("性", ""):dto.getSex()) : "");//根据需求,去掉男性女性中的性
        });

        //新生儿和双打
        if(!CollectionUtils.isEmpty(nursePatientDTOList)) {
            if ((!CollectionUtils.isEmpty(pbstetricWardList)) && "3".equals(type) && "2".equals(printNum)) {
                resultList.addAll(nursePatientDTOList);
                resultList.addAll(nursePatientDTOList);
                //排序
                resultList = resultList.stream().sorted(Comparator.comparing(PatientOrderServiceImpl::comparingByBedNo).thenComparing(PatientOrderServiceImpl::comparingByInpatNum))
                        .collect(Collectors.toList());
            } else {
                resultList.addAll(nursePatientDTOList);
            }
        }
        int totalLength = 0;
        //排序
        if (!CollectionUtils.isEmpty(resultList)) {
            totalLength = resultList.size();
            if (Integer.parseInt(page) != 0 && Integer.parseInt(pageSize) != 0) {
                resultList = resultList.stream().skip((Integer.parseInt(page) - 1) * Integer.parseInt(pageSize)).limit(Integer.parseInt(pageSize)).collect(Collectors.toList());
            }
        }

        PageInfo<NursePatientDTO> pageInfo = new PageInfo<NursePatientDTO>(resultList);
        pageInfo.setTotal(totalLength);
        return ResultGenerator.genOkResult(pageInfo);
    }

    private static Integer comparingByBedNo(NursePatientDTO nursePatientDTO) {
        return Integer.parseInt(nursePatientDTO.getBedNo());
    }
    private static String comparingByInpatNum(NursePatientDTO nursePatientDTO) {
        return nursePatientDTO.getInpatNum();
    }

    @Override
    public Result printPatientInfo(Commodel qrCodeMap) {
        String userId = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("zuul_id");
        List<Map<String, String>> qrCodeListMap = qrCodeMap.getList();
        PrintMarkEntity printMarkEntity = new PrintMarkEntity();
        for (int i = 0; i < qrCodeListMap.size(); i++) {
            Map<String, String> map = qrCodeListMap.get(i);
            String qrCode = map.get("qrCode");
            String type = map.get("type");
            if("2".equals(type)){
                String inpatNum = map.get("inpatNum");
                printMarkEntity.setInpatNum(inpatNum);
            }
            printMarkEntity.setQrCode(qrCode);
            printMarkEntity.setPrintUserId(userId);
            printMarkEntity.setType(type);
            printMarkEntity.initAdd();
            if("2".equals(type)){
                printMarkMapper.saveOrUpdate2(printMarkEntity);
            }else{
                printMarkMapper.saveOrUpdate(printMarkEntity);
            }

        }
        return ResultGenerator.genOkResult();
    }

    @Override
    public Result staticOrderList(String inpatNum, String beginTime, String endTime, String printType, String search) {

        return null;
    }

    @Override
    public Result staticOrderQRCode(String inpatNum, String beginTime, String endTime, String printType, String search) {
        List<Map<String, Object>> list = nurseOrdersMapper.staticOrderQRCode(inpatNum, beginTime, endTime);
        list.stream().forEach(map -> {
            computeAge(map);
            List<Map<String, Object>> orderList = nurseOrdersMapper.queryOrdersByInpatNum(map.get("inpatNum").toString(), map.get("orderNo").toString());
            map.put("orderList", orderList);
            List<Map<String, Object>> barCodeList = nurseOrdersMapper.queryBarcodeByInptNum(map.get("inpatNum").toString(), map.get("orderNo").toString());
            map.put("barCodeList", barCodeList);
            Map<String, Object> mainOrder = orderList.get(0);
            try {
                createFreQrCode(mainOrder, map, beginTime, endTime, printType);
            } catch (ParseException e) {
                e.printStackTrace();
            }

        });
        return ResultGenerator.genOkResult(list);
    }

    private void createFreQrCode(Map<String, Object> mainOrder111, Map<String, Object> result, String beginTime, String endTime, String printType) throws ParseException {
        List<Map<String, String>> qrCodeList = new ArrayList<>();
        String freq = result.get("freq") == null ? "" : result.get("freq").toString();
        // 长期医嘱
        if ("1".equals(result.get("orderType"))) {

            // 获取任务创建的开始时间和结束时间
            Date startDatetime = DateUtil.stringToDate(beginTime.compareTo(result.get("planBeginDatetime").toString()) > 0 ? beginTime : result.get("planBeginDatetime").toString());
            Date stopDatetime = DateUtil.stringToDate((result.get("planEndDatetime") == null || endTime.compareTo(result.get("planEndDatetime").toString()) < 0) ? endTime : result.get("planEndDatetime").toString());

            // 已打印
//			if("1".equals(printType)){
//				 startDatetime=DateUtil.stringToDate(result.get("planBeginDatetime").toString());
//			}


            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//            Date nowDate = DateUtil.stringToDate(beginTime + " 00:00:00");
////            String stopDatetime = result.get("planEndDatetime")==null?endTime + " 23:59:59":result.get("planEndDatetime").toString();
//            Date stopDate = DateUtil.stringToDate(stopDatetime);
//            Date nextDate = DateUtil.stringToDate(endTime + " 23:59:59");
//            nextDate = nextDate.before(stopDate)?nextDate:stopDate;
            CronExpression cronExpression = null;
            AtomicInteger hourNum = new AtomicInteger(0);
            AtomicInteger weekNum = new AtomicInteger(0);
            try {
                CronDescriber cronDescriber = JSONObject.parseObject((String) result.get("CRON_DESCRIBER"), CronDescriber.class);
                hourNum.set(cronDescriber.getSpecifiedHourNum());
                weekNum.set(cronDescriber.getSpecifiedDowNum());
                String expression = CronUtil.createCronExpression(cronDescriber, null);
                cronExpression = new CronExpression(expression);
            } catch (ParseException e) {
                logger.error("转换corn失败", e);
            }


            Date nextExecDate = startDatetime;
            String startTimeStr = result.get("planBeginDatetime").toString().substring(0, 10) + " 00:00:00";
            Date startTime = DateUtil.stringToDate(startTimeStr);
            AtomicInteger atomicInteger = new AtomicInteger(1);
            AtomicInteger atomicInteger2 = new AtomicInteger(1);
            //获得计划开始时间
            int startTimes = 0;
            Date startNextDay = DateUtil.getDateAfter(DateUtil.stringToDate(startTimeStr), 1);
            Date startDate = cronExpression.getNextValidTimeAfter((Date) result.get("planBeginDatetime"));
            Map<Date, Integer> startMap = new HashMap<>();
            while (null != startDate && startDate.before(startNextDay)) {
                startTimes++;
                startMap.put(startDate, startTimes);
                startDate = cronExpression.getNextValidTimeAfter(startDate);
            }
            if ("1".equals(result.get("TIMEMODE"))) {
                Date begin = DateUtil.stringToDate(beginTime);
                Date resultDate = begin.compareTo(startTime) == 0 ? startTime : begin;
                nextExecDate = cronExpression.getNextValidTimeAfter(resultDate);
            }
            while (nextExecDate.before(stopDatetime)) {
                if ("0".equals(result.get("TIMEMODE"))) {
                    nextExecDate = cronExpression.getNextValidTimeAfter(nextExecDate);
                }
                if (nextExecDate != null && (nextExecDate.before(stopDatetime) || nextExecDate.equals(stopDatetime))) {
                    //此次执行时间需要在计划开始时间之后
                    if (nextExecDate.after(DateUtil.stringToDate(result.get("planBeginDatetime").toString())) || "1".equals(result.get("TIMEMODE"))) {
                        StringBuffer serialNo = new StringBuffer();
                        int cycleAllNum = hourNum.get() * (weekNum.get() == 0 ? 1 : weekNum.get()); //Q4H = 6 , TID = 3 , TIW = 3
                        int cycleNum = cycleAllNum / Integer.valueOf((String) result.get("EXE_NUMBER"));//Q4H = 6 , TID = 1 , TIW = 1 || EXE_CYCLE_STAMP（Q4H = 14400 , TID = 86400 , TIW = 604800)
                        long cycle;
                        if ("1".equals(result.get("TIMEMODE"))) {
                            cycle = (nextExecDate.getTime() - startTime.getTime()) / 1000 / Integer.parseInt((String) result.get("exeCycleStamp")) + 1;
                        } else {
                            if (nextExecDate.before(startDate)) {
                                cycle = startMap.get(nextExecDate);
                            } else {
                                long allNums = (cycleAllNum * ((((nextExecDate.getTime() - startDate.getTime()) / 1000 / Integer.parseInt((String) result.get("exeCycleStamp"))) / cycleNum)));
                                cycle = startTimes + (allNums < 0 ? 0 : allNums) + 1;
                            }
                        }
                        if (cycle != atomicInteger.longValue() && atomicInteger.get() == 1) {
                            atomicInteger2 = new AtomicInteger(1);
                            atomicInteger.set((int) cycle);
                        }
                        serialNo.append("_").append(atomicInteger.getAndIncrement()).append("_").append(atomicInteger2.get());
                        Map<String, String> map = new HashMap<>();
                        String qrCode = result.get("inpatOrderId") + serialNo.toString();
                        map.put("qrCode", qrCode);
                        map.put("execDate", sdf.format(nextExecDate));
                        String times = printMarkMapper.countByQrCode(qrCode, NurseEnum.PRINT_THREE.getIndex());
                        times = StringUtils.isBlank(times) ? "0" : times;
                        map.put("times", times);
                        if ("0".equals(times) && printType.equals("0")) {
                            // 未打印类型，打印次数为0
                            qrCodeList.add(map);
                        } else if (!"0".equals(times) && printType.equals("1")) {
                            // 打印类型，打印次数不为0
                            qrCodeList.add(map);
                        }

                    }
                }
                if ("1".equals(result.get("TIMEMODE"))) {
                    //计算下个创建任务的时间
                    nextExecDate = DateUtil.increasedSeconds(nextExecDate, Integer.parseInt((String) result.get("exeCycleStamp")));
                    //如果间隔时间小于明天0点,并且等于第二天0点，那就创建任务，防止第二天0点只计算间隔时间，可能会忽略本身的0点，那就创建任务
                }
            }
        } else { // 临时医嘱
            Map<String, String> map = new HashMap<>();
            String qrCode = result.get("inpatOrderId") + "_1";
            map.put("qrCode", qrCode);
            map.put("execDate", String.valueOf(result.get("orderExecTime")));
            String times = printMarkMapper.countByQrCode(qrCode, NurseEnum.PRINT_THREE.getIndex());
            times = StringUtils.isBlank(times) ? "0" : times;
            map.put("times", times);
            if ("0".equals(times) && printType.equals("0")) {
                // 未打印类型，打印次数为0
                qrCodeList.add(map);
            } else if (!"0".equals(times) && printType.equals("1")) {
                // 打印类型，打印次数不为0
                qrCodeList.add(map);
            }
        }
        result.put("qrCodeList", qrCodeList);
    }


    @Override
    public Result administrationType() {
        List<Map<String, String>> list = nurseOrdersMapper.selectAdministrationType();
        return ResultGenerator.genOkResult(list);
    }

    @Override
    public List<SpecilmenDetailLisDto> queryLabSpecimenList(LabSpecimenSearchDto searchDto) {
        String separator = "-";
        if (searchDto.getInpatNum().split(separator).length == 0) {
            return null;
        }
        Map<String, Object> param = new HashMap<>(4);
        param.put("InpatNum", searchDto.getInpatNum().split(separator)[0]);
        param.put("BeginDate", searchDto.getBeginTime());
        param.put("EndDate", searchDto.getEndTime());
        JSONObject jsonObject = HttpClientUtil.sendPost(lisUrl, param);
        if (jsonObject.getString("Data") != null && StringUtils.isNotBlank(jsonObject.getJSONObject("Data").getString("RowNums"))) {
            System.out.println(jsonObject.getString("Data"));
            List<SpecilmenDetailLisDto> dtos = JSON.parseArray(jsonObject.getJSONObject("Data").getString("RowNums"), SpecilmenDetailLisDto.class);
            if (CollectionUtils.isEmpty(dtos)) {
                return dtos;
            }
            logger.info("lis采集的数量:" + dtos.size());
            for (SpecilmenDetailLisDto dto : dtos) {
                Integer count = nurseOrdersMapper.querySepcimenDetailCount(dto.getSpecimenNum(), dto.getRegNum(), dto.getSeNum());
                if (Objects.equals(count, 0)) {
                    dto.setInpatNum(searchDto.getInpatNum().trim());
                    dto.setVersion("1");
                    nurseOrdersMapper.insertSepcimen(dto);
                }
                SpecimenExtraDto specimenExtraDto = nurseOrdersMapper.querySpecimenExtra(dto.getRegNum(), dto.getSeNum());
                if (specimenExtraDto != null) {
                    dto.setReqDeptName(specimenExtraDto.getReqDeptName());
                    dto.setOrderTime(specimenExtraDto.getOrderTime());
                }
            }
            return dtos;
        }
        return null;
    }

    @Override
    public Result labSync(String wardDeptId) {
        //根据病区id查询所有住院号
        List<Map<String, String>> patientList = nurseOrdersMapper.queryPatientByWardId(wardDeptId);
        //根据住院号查询该住院号的检验医嘱是否产生了报告，获取最早未产生报告的检验医嘱时间
        List<SpecilmenDetailLisDto> list = new CopyOnWriteArrayList<>();
        patientList.parallelStream().forEach(x -> {
            Map<String, Object> param = new HashMap<>(4);
            param.put("InpatNum", x.get("INPAT_NUM").split("-")[0]);
            param.put("BeginDate", x.get("CREATE_DATETIME"));
            param.put("EndDate", x.get("END_DATATIME"));
            JSONObject jsonObject = HttpClientUtil.sendPost(lisUrl, param);
            if (jsonObject.getString("Data") != null && StringUtils.isNotBlank(jsonObject.getJSONObject("Data").getString("RowNums"))) {
                System.out.println(jsonObject.getString("Data"));
                List<SpecilmenDetailLisDto> dtos = JSON.parseArray(jsonObject.getJSONObject("Data").getString("RowNums"), SpecilmenDetailLisDto.class);
                if (!CollectionUtils.isEmpty(dtos)) {
                    logger.info("lis采集的数量:" + dtos.size());
                    for (SpecilmenDetailLisDto dto : dtos) {
                        Integer count = nurseOrdersMapper.querySepcimenDetailCount(dto.getSpecimenNum(), dto.getRegNum(), dto.getSeNum());
                        if (Objects.equals(count, 0)) {
                            dto.setInpatNum(x.get("INPAT_NUM").trim());
                            dto.setVersion("1");
                            list.add(dto);
                        }
                    }
                }
            }
        });
        if (!CollectionUtils.isEmpty(list)) nurseOrdersMapper.insertSepcimenList(list);
        return ResultGenerator.genOkResult();
    }

}
